package Server;

import Server.Cache.MsgSession;
import Server.Factory.MessageFactory;
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.ReentrantReadWriteLock;


public class MessageQueue {

    //private static final Queue<MsgSession> MESSAGE = new ConcurrentLinkedDeque<>();

    private static final Queue<MsgSession> MESSAGE = new LinkedList<>();

    private boolean isRunning = true;

    public MessageQueue(){
        start();
    }

    public void start(){
        if(!isRunning) {
            isRunning = true;
        }
        Thread msgThread = new WorkThread();
        msgThread.start();

    }

    public synchronized void acceptMsg(MsgSession session){
        if(session == null){
            throw new NullPointerException("task is null");
        }
        MESSAGE.add(session);
    }


    public void shutDown(){
        isRunning = false;
    }

    private synchronized void runTask(){
        if (MESSAGE.isEmpty()) {
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        MsgSession session;
        if (!MESSAGE.isEmpty()) {
            session = MESSAGE.poll();
        } else {
            session = null;
        }
        try {
            if (session != null) {
                switch (session.getChannelState()) {
                    case RUNNING:
                        MessageFactory.getInstance().dispatch(session);
                        break;
                    case ONLINE:
                        session.saveChannel();
                        break;
                    case OFFLINE:
                        session.disconnected();
                        break;
                    default:
                        throw new ArrayIndexOutOfBoundsException(session.getChannelId() + " is unKnow");
                }
            }
        } catch (Exception e) {
            acceptMsg(session);
        }
    }


    private class WorkThread extends Thread{
        public WorkThread(){}
        @Override
        public void run(){
            while (isRunning) {
                runTask();
            }
        }
    }


}
